"""
文件名: Base.py]
作用: 对selenium进行二次封装
    1.打开浏览器
    2.打开网址
    3.元素定位
    4.元素操作
    5.元素属性获取
    ....
"""
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains


def open_browser(browser: str = "chrome"):
    """
    打开浏览器
    :param browser: 浏览器名称
    :return:
    """
    if browser.lower() == "chrome":
        return webdriver.Chrome()
    elif browser.lower() == "firefox":
        return webdriver.Firefox()
    elif browser.lower() == "edge":
        return webdriver.Edge()
    else:
        print("请输入正确的浏览器:例如Chrome,Firefox,Edge")


class Base(object):
    def __init__(self, driver):
        self.driver = driver
        self.driver.maximize_window()

    def open_url(self, url):
        """
        打开网址
        :param url: 网址
        :return:
        """
        try:
            self.driver.get(url)
        except:
            print(f"输入的{url}地址不正确")

    def find_element(self, locator: tuple, timeout: int = 10):
        """
        查找单个元素,如果找到返回元素,反之,提示元素没找到,并且返回False
        :param locator:定位器
        :param timeout:最长等待之间
        :return:element
        """
        try:
            return WebDriverWait(self.driver, timeout).until(EC.presence_of_element_located(locator))
        except:
            print(f"元素{locator}没有找到")
            return False

    def find_elements(self, locator: tuple, timeout: int = 10):
        """
        查找多个元素,返回一组元素列表,反之,提示没有找到,并且返回False
        :param locator: 定位器
        :param timeout: 最长等待时间
        :return: list
        """
        try:
            return WebDriverWait(self.driver, timeout).until(EC.presence_of_all_elements_located(locator))
        except:
            print(f"元素{locator}没有找到")
            return False

    def click(self, locator: tuple, timeout: int = 10):
        """
        点击
        :param locator: 定位器
        :param timeout: 最长等待时间
        :return:
        """
        try:
            element = self.find_element(locator=locator, timeout=timeout)
            element.click()
        except:
            print(f'元素{locator}不存在,无法点击')
            return False

    def send_keys(self, text, locator: tuple, timeout: int = 10):
        """
        输入内容
        :param text: 输入内容
        :param locator: 定位器
        :param timeout: 最长等待时长
        :return:
        """
        try:
            element = self.find_element(locator=locator, timeout=timeout)
            element.clear()
            element.send_keys(text)
        except:
            print(f'元素{locator}不存在,无法输入')

    def get_element_text(self, locator: tuple, timeout: int = 10):
        """
        获取元素文本,返回text文本值,否则返回False
        :param locator: 定位器
        :param timeout: 最长等待时间
        :return: text
        """
        try:
            element = self.find_element(locator=locator, timeout=timeout)
            return element.text
        except:
            print("元素文本值没有获取到")
            return False

    def get_element_value(self, locator: tuple, timeout: int = 10):
        """
        获取value属性对应的值,找到则返回属性值,否则返回False
        :param locator: 定位器
        :param timeout: 最长等待时长
        :return: value属性值
        """
        try:
            element = self.find_element(locator=locator, timeout=timeout)
            return element.get_attribute("value")
        except:
            print("value属性值没有获取到")
            return False

    def close_browser(self):
        """
        关闭浏览器
        :return:
        """
        self.driver.quit()

    def is_text_in_element(self, text, locator: tuple, timeout: int = 10):
        """
        判断输入的文本是否与元素的相同,相同返回True,否则返回False
        :return:
        """
        try:
            element = self.find_element(locator=locator, timeout=timeout)
            element_text = element.text
            if element_text:
                return element_text == text
            else:
                return False
        except:
            print(f"元素{locator}没有找到")
            return False

    def click_radio(self, locator: tuple, timeout: int = 10):
        """
        单选框点击
        :param locator: 定位器
        :param timeout: 最长等待时间
        :return:
        """
        try:
            element = self.find_element(locator=locator, timeout=timeout)
            if element.is_selected():
                pass
            else:
                element.click()
        except:
            print(f'元素{locator}不存在,无法点击')

    def select_drop_down_menu(self, index: int, locator: tuple, timeout: int = 10):
        """
        下拉菜单选择,元素定位准确,返回相应的值,否则返回False
        :param locator: 定位器
        :param timeout: 最长等待时间
        :return:
        """
        try:
            element = self.find_element(locator=locator, timeout=timeout)
            select = Select(element)
            return select.select_by_index(index=index)
        except:
            print(f'元素{locator}不存在,无法点击')
            return False

    def click_back(self):
        """回退"""
        self.driver.back()

    def is_alert(self):
        """
        捕获弹窗
        :return:
        """
        try:
            self.driver.switch_to.alert
        except:
            return False
        else:
            return True

    def remove_alerta_window(self, id):
        """
        去除页面弹窗
        :return:
        """
        js = f'document.getElementById("{id}").style.display="none";'
        self.driver.execute_script(js)

    def get_alert_accept_text(self, timeout: int = 10):
        """
        获取弹窗文本,点击确定
        :param timeout:最长等待时长
        :return:
        """
        try:
            alert = WebDriverWait(self.driver, timeout).until(EC.alert_is_present())
            text = alert.text
            alert.accept()
            return text
        except:
            print("弹窗没有找到")
            return False

    def get_alert_dismiss(self, timeout: int = 10):
        """
        获取弹窗文本,点击取消
        :param timeout:最长等待时长
        :return:
        """
        try:
            alert = WebDriverWait(self.driver, timeout).until(EC.alert_is_present())
            text = alert.text
            alert.dismiss()
            return text
        except:
            print("弹窗没有找到")
            return False

    def mouse_over(self, locator: tuple, timeout: int = 10):
        """鼠标悬停"""
        element = self.find_element(locator=locator, timeout=timeout)
        ActionChains(self.driver).move_to_element(element).perform()

    def get_text(self, locator: tuple, timeout: int = 10):
        """获取元素文本"""
        try:
            element = self.find_element(locator=locator, timeout=timeout)
            element_text = element.text
            return element_text
        except:
            print(f"{locator}元素没有找到")
            return False

    def join_iframe(self, frame):
        """
        进入iframe
        :return:
        """
        try:
            self.driver.switch_to.frame(frame)
            print(f'进入{frame}成功')
        except:
            print(f'未找到{frame}这个iframe')
            return False

    def quit_iframe(self):
        """
        退出iframe
        :return:
        """
        try:
            self.driver.switch_to.default_content()
            print('已退出iframe')
        except:
            print('退出失败')

    def skip_login(self):
        """登录百度账号,查看登录前后的cookie区别,找到对应的name与value,然后添加cookie,绕过登录页面"""
        cookies = [
            {"name": "ECS[password]",
             "value": "1365b795ef1b4b519e81018aed0e6e8d"
             },
            {"name": "ECS[user_id]",
             "value": "3"
             }
        ]
        # 添加cookie
        for cookie in cookies:
            self.driver.add_cookie(cookie)
        # 刷新
        self.driver.refresh()
    def refresh(self):
        self.driver.refresh()


if __name__ == '__main__':
    import time

    # 打开浏览器
    driver = open_browser()
    # 实例化一个base类
    base = Base(driver)
    # 打开百度网址
    base.open_url("http://www.baidu.com")
    # 定位百度输入框
    # search_loc = ("id", "kw")
    # 定位百度一下按钮
    # click_loc = ("id", "su")
    # 定位百度首页设置元素
    # setting_loc=("id",'s-usersetting-top')
    # 定位设置元素获取设置文本值
    # print(base.get_ele/ment_text(setting_loc))
    # 定位百度一下按钮元素,获取value属性值
    # print(base.get_element_value(search_loc))
    # 百度输入框输入破设计模式
    # base.send_keys(locator=search_loc, text="PO设计模式")
    # 点击百度一下按钮
    # base.click(locator=click_loc)
    locator = ("id", "s-usersetting-top")
    base.mouse_over(locator)
    time.sleep(5)
    # 关闭浏览器
    base.close_browser()
